package com.jinly.ryder.deploy.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.jinly.ryder.deploy.dao.DeployRecordMapper;
import com.jinly.ryder.deploy.dao.entity.DeployRecordDO;
import com.jinly.ryder.deploy.service.DeployRecordService;
import com.jinly.ryder.deploy.service.mapping.DeployRecordMapping;
import com.jinly.ryder.deploy.service.model.DeployProgress;
import com.jinly.ryder.deploy.service.model.DeployRecord;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

@Slf4j
@Service
@RequiredArgsConstructor
public class DeployRecordServiceImpl implements DeployRecordService {

    private final DeployRecordMapper deployRecordMapper;
    private final DeployRecordMapping deployRecordMapping;

    private Cache<String, DeployProgress> deployProcessCache = Caffeine.newBuilder()
            .expireAfterWrite(60, TimeUnit.MINUTES)
            .initialCapacity(100)
            .maximumSize(1000)
            .build();

    @Override
    public void updateDeployProgress(DeployProgress deployProgress) {
        deployProcessCache.put(deployProgress.getHost() + "_" + deployProgress.getPort(), deployProgress);
    }

    @Override
    public DeployProgress getDeployProgress(String host, Integer port) {
        return deployProcessCache.get(host + "_" + port, k -> null);

    }

    @Override
    public void removeDeployProgress(String host, Integer port) {
        deployProcessCache.invalidate(host + "_" + port);
    }

    @Override
    public void createRecord(DeployRecord deployRecord) {
        DeployRecordDO deployRecordDO = deployRecordMapping.toEntity(deployRecord);
        deployRecordMapper.insert(deployRecordDO);
        deployRecord.setId(deployRecordDO.getId());
    }

    @Override
    public void updateRecord(DeployRecord deployRecord) {
        deployRecordMapper.updateById(deployRecordMapping.toEntity(deployRecord));
    }

    @Override
    public DeployRecord getRecord(Long recordId) {
        return deployRecordMapping.toModel(deployRecordMapper.selectById(recordId));
    }

    @Override
    public Page<DeployRecord> queryRecordPage(Page page, Integer instanceId) {
        Wrapper<DeployRecordDO> queryWrapper = new QueryWrapper<DeployRecordDO>().lambda()
                .eq(DeployRecordDO::getInstanceId, instanceId)
                .select(DeployRecordDO::getId,
                        DeployRecordDO::getDeployType,
                        DeployRecordDO::getInstanceId,
                        DeployRecordDO::getBeginTime,
                        DeployRecordDO::getEndTime,
//                        DeployRecordDO::getDeployParamsJson,
                        DeployRecordDO::getOperator,
                        DeployRecordDO::getSuccess
                ).orderByDesc(DeployRecordDO::getId);
        return deployRecordMapping.toModelPage(deployRecordMapper.selectPage(page, queryWrapper));
    }

    @Override
    public DeployRecord lastRecordByApplyId(Long applyId) {
        Wrapper<DeployRecordDO> queryWrapper = new QueryWrapper<DeployRecordDO>().lambda()
                .eq(DeployRecordDO::getApplyId, applyId)
                .isNotNull(DeployRecordDO::getSuccess)
                .orderByDesc(DeployRecordDO::getUpdated)
                .select(DeployRecordDO::getId,
                        DeployRecordDO::getDeployType,
                        DeployRecordDO::getInstanceId,
                        DeployRecordDO::getBeginTime,
                        DeployRecordDO::getEndTime,
                        DeployRecordDO::getOperator,
                        DeployRecordDO::getUpdated
                ).last("limit 1");
        return deployRecordMapping.toModel(deployRecordMapper.selectOne(queryWrapper));
    }

}
